package com.dream.utils.date;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;

/**
 * populate a date from  String to Date
 * @copyright evan
 * @author evan
 * @Revision
 * @date 2012/8/18
 */
public class DateCalculateUtils {
	
	/**
	 * get year
	 * @param date
	 * @return
	 */
	public static int getYear(Date date){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return  calendar.get(Calendar.YEAR);
	}
	
	/**
	 * get month
	 * @param date
	 * @return
	 */
	public static int getMonth(Date date){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return  calendar.get(Calendar.MONTH)+1;	
	}
	
	/**
	 * get day
	 * @param date
	 * @return
	 */
	public static int getDay(Date date){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return  calendar.get(Calendar.DAY_OF_MONTH);	
	}
	
	/**
	 * get week
	 * @param date
	 * @return
	 */
	public static WeekType getWeek(Date date){
		Calendar calendar = Calendar.getInstance();
		calendar.setFirstDayOfWeek(Calendar.MONDAY);
		calendar.setTime(date);
		return  WeekType.instance(calendar.get(Calendar.DAY_OF_WEEK));	
	}
	
	/**
	 * get Monday 
	 * @param date
	 * @return
	 */
	public static Date getMonday(Date date){
		return getWeekByAdjust(date,WeekType.MONDAY);	
	}
	
	/**
	 * get Sunday 
	 * @param date
	 * @return
	 */
	public static Date getSunday(Date date){
		return getWeekByAdjust(date,WeekType.SUNDAY);	
	}
	
	/**
	 * 
	 * @param date
	 * @param week
	 * @return
	 */
	public static Date getWeekByAdjust(Date date, WeekType week){
		Calendar calendar = Calendar.getInstance();
		calendar.setFirstDayOfWeek(Calendar.MONDAY);
		calendar.setTime(date);
		calendar.set(Calendar.DAY_OF_WEEK,week.toInteger());
		return  calendar.getTime();	
	}
	
	/**
	 * add some years
	 * @param date
	 * @param years
	 * @return
	 */
	public static Date addYears(Date date, int years){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.YEAR, years);
		return  calendar.getTime();
	}
	/**
	 * add some month
	 * @param date
	 * @param month
	 * @return
	 */
	public static Date addMonths(Date date, int month){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.MONTH, month);
		return  calendar.getTime();
	}
	
	/**
	 * 
	 * @param date
	 * @param week
	 * @return
	 */
	public static Date addWeeks(Date date, int week) {

		return getNewDate(date, week, TimeType.WEEK);
	}
	
	/**
	 * add some day
	 * @param date
	 * @param day
	 * @return
	 */
	public static Date addDays(Date date, int day) {
		return getNewDate(date, day, TimeType.DAY);
	}
	
	/**
	 * add some hours
	 * @param date
	 * @param hour
	 * @return
	 */
	public static Date addHours(Date date, int hour) {

		return getNewDate(date, hour, TimeType.HOUR);
	}


	/**
	 * add some minute
	 * @param date
	 * @param min
	 * @return
	 */
	public static Date addMinutes(Date date, int min) {

		return getNewDate(date, min, TimeType.MINITE);
	}

	/**
	 * 
	 * @param date
	 * @param sec
	 * @return
	 */
	public static Date addSeconds(Date date, int sec) {

		return getNewDate(date, sec, TimeType.SECOND);
	}

	/**
	 * 
	 * @param date
	 * @param n
	 * @param type
	 * @return
	 */
	private static Date getNewDate(Date date, int n, TimeType type) {
		Date mydate = date;

		if (null == date) {
			mydate = new Date();
		}

		long ms = mydate.getTime();
		ms += type.getMillSeconds() * n;

		return new Date(ms);
	}
	
	
	/**
	 * the begin point of this day
	 * @param date
	 * @param pattern
	 * @return
	 */
	public static Date toBeginPointDay(Date date) {

		Calendar calendar1 = Calendar.getInstance();
		calendar1.setTime(date);

		Calendar calendar = Calendar.getInstance();
		calendar.set(calendar1.get(Calendar.YEAR), calendar1.get(Calendar.MONTH),
				calendar1.get(Calendar.DATE));
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();

	}
	
	/**
	 * to time 8:30 AM from initial time
	 * 
	 * @return
	 */
	public static Date toTime830(Date date) {
		date = toBeginPointDay(date);
		date = addHours(date, 8);
		date = addMinutes(date, 30);
		return date;
	}
	
	/**
	 * the noon point of this day
	 * @return
	 */
	public static Date toMiddlePointDay(Date date) {

		date = toBeginPointDay(date);
		date = addHours(date, 12);
		return date;

	}
	
	/**
	 * the end point of this day
	 * @return
	 */
	public static Date toEndPointDay(Date date) {

		date = toBeginPointDay(date);
		date = addHours(date, 23);
		date = addMinutes(date, 59);
		date = addSeconds(date, 59);
		return date;

	}

	
	/**
	 * first day of this year
	 * @param date
	 * @return
	 */
	public static Date toYearBegin(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.DAY_OF_YEAR, 1);
		date = calendar.getTime();
		return toBeginPointDay(date);
	}

	/**
	 * last day of year
	 * @return
	 */
	public static Date toYearEnd(Date date) {

		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		int end = calendar.getActualMaximum(Calendar.DAY_OF_YEAR);
		calendar.set(Calendar.DAY_OF_YEAR, end);
		date = calendar.getTime();
		return toEndPointDay(date);
	}
	
	/**
	 * first day of month
	 * @return
	 */
	public static Date  toMonthBegin(Date date) {
		
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		date = calendar.getTime();
		return toBeginPointDay(date);
	}

	/**
	 * last day of month
	 * @return
	 */
	public static Date toMonthEnd(Date date) {
		
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		int end = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
		calendar.set(Calendar.DAY_OF_MONTH, end);
		date = calendar.getTime();
		return  toEndPointDay(date);
	}
	
	/**
	 * first day of this week
	 * @return
	 */
	public static Date toWeekBegin(Date date) {

		return toBeginPointDay(getMonday(date));

	}
	
	/**
	 * last day of this week
	 * @return
	 */
	public static Date toWeekEnd(Date date){
		return toEndPointDay(getSunday(date));
	}
	
	/**
	 * 
	 * @author Tony	
	 * @date 2013-10-28
	 * @param smdate
	 * @param bdate
	 * @return
	 * @throws ParseException
	 */
	public static int daysBetween(Date smdate, Date bdate) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(smdate);
		long time1 = cal.getTimeInMillis();
		cal.setTime(bdate);
		long time2 = cal.getTimeInMillis();
		long between_days = (time2 - time1) / (1000 * 3600 * 24);

		return Integer.parseInt(String.valueOf(between_days));
	}
}
